﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace HCMUS_SearchService_Group2
{
    /////////////////////////////////////////////////
    /// \brief Lớp static hỗ trợ search.
    /// \author Trần Minh Nhật -   0912322.
    /// \details <h3>Cung cấp các phương thức giúp việc Search trở nên dễ dàng hơn</h3>
    ////////////////////////////////////////////////
    public  class SearchHelper
    {
        public const int SERVICE = 1;
        public const int STREET = 2;
        public const int WARD = 3;
        public const int DISTRICT = 4;

        private static List<LocationKeyDTO> locationKeys;

        public static List<LocationKeyDTO> LocationKeys
        {
            get { return SearchHelper.locationKeys; }
        }

        private static List<LocationDTO> locations;

        public static List<LocationDTO> Locations
        {
            get { return SearchHelper.locations; }
        }

        private static List<StreetKeyDTO> streetKeys;

        public static List<StreetKeyDTO> StreetKeys
        {
            get { return SearchHelper.streetKeys; }
        }

        private static List<StreetDTO> streets;

        public static List<StreetDTO> Streets
        {
            get { return SearchHelper.streets; }
        }

        private static List<WardKeyDTO> wardKeys;

        public static List<WardKeyDTO> WardKeys
        {
            get { return SearchHelper.wardKeys; }
        }

        private static List<WardDTO> wards;

        public static List<WardDTO> Wards
        {
            get { return SearchHelper.wards; }
        }

        private static List<DistrictKeyDTO> districtKeys;

        public static List<DistrictKeyDTO> DistrictKeys
        {
            get { return SearchHelper.districtKeys; }
        }

        private static List<DistrictDTO> districts;

        public static List<DistrictDTO> Districts
        {
            get { return SearchHelper.districts; }
        }

        private static List<CityKeyDTO> cityKeys;

        public static List<CityKeyDTO> CityKeys
        {
            get { return SearchHelper.cityKeys; }
        }

        private static List<CityDTO> citys;

        public static List<CityDTO> Citys
        {
            get { return citys; }
        }

        private static List<ServiceKeyDTO> serviceKeys;

        public static List<ServiceKeyDTO> ServiceKeys
        {
            get { return SearchHelper.serviceKeys; }
        }

        private static List<ServiceDTO> services;

        public static List<ServiceDTO> Services
        {
            get { return SearchHelper.services; }
        }

        private static List<DataDTO> datas;

        public static List<DataDTO> Datas
        {
            get { return SearchHelper.datas; }
        }

        private static List<DetailDataDTO> detailDatas;

        public static List<DetailDataDTO> DetailDatas
        {
            get { return SearchHelper.detailDatas; }
        }

        private static List<ServiceDetailDTO> serviceDetails;

        public static List<ServiceDetailDTO> ServiceDetails
        {
            get { return SearchHelper.serviceDetails; }
        }

        private readonly static DataDAO objectDataDAO = new DataDAO();

        public static DataDAO ObjectDataDAO
        {
            get { return SearchHelper.objectDataDAO; }
        }

        public static void InitData()
        {            
            cityKeys = CityKeyWordDAO.GetAllDTOKeyWord();
            serviceKeys = ServiceKeyWordDAO.GetAllDTOKeyWord();
            districtKeys = DistrictKeyDAO.GetAllDTOKeyWord();            
            wardKeys = WardKeyWordDAO.GetAllDTOKeyWord();            
            streetKeys = StreetKeyWordDAO.GetAllDTOKeyWord();
            locationKeys = LocationKeyDAO.GetAllDTOKeyWord();

            services = SearchHelper.GetAllServiceDTO();                       
            citys = SearchHelper.GetAllCityDTO();
            districts = SearchHelper.GetAllDistrictDTO();
            wards = SearchHelper.GetAllWardDTO();            
            detailDatas = SearchHelper.GetAllDetailDataDTO();
            serviceDetails = SearchHelper.GetAllServiceDetailDTO();
            streets = SearchHelper.GetAllStreetDTO();
            locations = SearchHelper.GetAllLocationDTO();
            datas = SearchHelper.GetAllDataDTO();
            //DataConnectionHelper.Context = null;
        }

        public static void Dispose()
        {
            locationKeys = null;
            cityKeys = null;
            districtKeys = null;
            streetKeys = null;
            wardKeys = null;
            serviceKeys = null;

            services = null;
            wards = null;
            locations = null;
            citys = null;
            districts = null;
            streets = null;
            datas = null;
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS LocationDTO
        /// \param[in] Không.
        /// \returns  List<LocationDTO>.
        /// \details <h3>Trả về danh sách tất cả các LocationDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<LocationDTO> GetAllLocationDTO()
        {
            LocationDAO locationDAO = new LocationDAO();
            List<ObjectDTO> objects = locationDAO.GetAllDTO();
            return SearchHelper.ConvertLocationDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS StreetDTO
        /// \param[in] Không.
        /// \returns  List<StreetDTO>.
        /// \details <h3>Trả về danh sách tất cả các StreetDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<StreetDTO> GetAllStreetDTO()
        {
            StreetDAO streetDAO = new StreetDAO();
            List<ObjectDTO> objects = streetDAO.GetAllDTO();
            return SearchHelper.ConvertStreetDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS WardDTO
        /// \param[in] Không.
        /// \returns  List<WardDTO>.
        /// \details <h3>Trả về danh sách tất cả các WardDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<WardDTO> GetAllWardDTO()
        {
            WardDAO wardDAO = new WardDAO();
            List<ObjectDTO> objects = wardDAO.GetAllDTO();
            return SearchHelper.ConvertWardDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS CityDTO
        /// \param[in] Không.
        /// \returns  List<CityDTO>.
        /// \details <h3>Trả về danh sách tất cả các CityDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<CityDTO> GetAllCityDTO()
        {
            CityDAO cityDAO = new CityDAO();
            List<ObjectDTO> objects = cityDAO.GetAllDTO();
            return SearchHelper.ConvertCityDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS ServiceDTO
        /// \param[in] Không.
        /// \returns  List<ServiceDTO>.
        /// \details <h3>Trả về danh sách tất cả các ServiceDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<ServiceDTO> GetAllServiceDTO()
        {
            ServiceDAO serviceDAO = new ServiceDAO();
            List<ObjectDTO> objects = serviceDAO.GetAllDTO();
            return SearchHelper.ConvertServiceDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS DistrictDTO
        /// \param[in] Không.
        /// \returns  List<DistrictDTO>.
        /// \details <h3>Trả về danh sách tất cả các DistrictDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<DistrictDTO> GetAllDistrictDTO()
        {
            DistrictDAO districtDAO = new DistrictDAO();
            List<ObjectDTO> objects = districtDAO.GetAllDTO();
            return SearchHelper.ConvertDistrictDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS ServiceDetailDTO
        /// \param[in] Không.
        /// \returns  List<ServiceDetailDTO>.
        /// \details <h3>Trả về danh sách tất cả các ServiceDetailDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<ServiceDetailDTO> GetAllServiceDetailDTO()
        {
            
            List<ObjectDTO> objects = ServiceDetailDAO.GetAllServiceDetailDTO();
            return SearchHelper.ConvertServiceDetailDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS DetailDataDTO
        /// \param[in] Không.
        /// \returns  List<DetailDataDTO>.
        /// \details <h3>Trả về danh sách tất cả các DetailDataDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<DetailDataDTO> GetAllDetailDataDTO()
        {
            
            List<ObjectDTO> objects = ServiceDetailDAO.GetAllDetailDataDTO();
            return SearchHelper.ConvertDetailDataDTO(objects);
        }

        /////////////////////////////////////////////////
        /// \brief Lấy DS DataDTO
        /// \param[in] Không.
        /// \returns  List<DataDTO>.
        /// \details <h3>Trả về danh sách tất cả các DataDTO trong Database.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> GetAllDataDTO()
        {
            
            List<DataDTO> objects = DataDAO.GetAllDTO();
            return objects;
        }           

        /////////////////////////////////////////////////
        /// \brief Hàm lấy danh sách các DTO
        /// \param[in] int mode.
        /// \param[in] string input.
        /// \returns List(string) .
        /// \details <h3>Trả về danh sách các đối tượng theo mode tương ứng mà có chứa chuỗi input hoặc năm trong chuỗi input.</h3>
        /////////////////////////////////////////////////
        public static List<string> GetListItem(int mode, string input)
        {
            List<string> result = new List<string>();

            /// - Bước 1: Xác định Search theo loại nào 
            switch (mode)
            {
                case SERVICE:

                    /// - Bước 2: Lấy DS các DTO
                    /// \see ServiceDAO.GetAllDTO();
                    for (int i = 0; i < Services.Count; i++)
                    {
                        /// \see TranslateHelper.FormatInputString(string);
                        string temp = TranslateHelper.FormatInputString(Services[i].ServiceName);

                        /// - Bước 3: Kiểm tra Service đó có bắt đầu bằng chuỗi cần kiểm tra không hoặc ngược lại.
                        if (temp.StartsWith(input) || input.StartsWith(temp))
                        {
                            /// - Bước 4: Nếu thỏa thêm vào danh sách trả về.
                            result.Add(Services[i].ServiceName);
                        }

                        if (result.Count >= AutoCompleteHelper.MAXSUGGEST)
                        {
                            break;
                        }
                    }

                    break;
                case STREET:

                    /// - Bước 2: Lấy DS các DTO
                    /// \see StreetDAO.GetAllDTO();                 
                    for (int i = 0; i < Streets.Count; i++)
                    {
                        /// \see TranslateHelper.FormatInputString(string);
                        string temp = TranslateHelper.FormatInputString(Streets[i].StreetName);

                        /// - Bước 3: Kiểm tra Service đó có bắt đầu bằng chuỗi cần kiểm tra không hoặc ngược lại.
                        if (temp.StartsWith(input) || input.StartsWith(temp))
                        {
                            /// - Bước 4: Nếu thỏa thêm vào danh sách trả về.
                            result.Add(Streets[i].StreetName);
                        }

                        if (result.Count >= AutoCompleteHelper.MAXSUGGEST)
                        {
                            break;
                        }
                    }

                    break;
                case WARD:

                    /// - Bước 2: Lấy DS các DTO
                    /// \see WardDAO.GetAllDTO();
                    for (int i = 0; i < Wards.Count; i++)
                    {
                        /// \see TranslateHelper.FormatInputString(string);
                        string temp = TranslateHelper.FormatInputString(Wards[i].WardName);

                        /// - Bước 3: Kiểm tra Service đó có bắt đầu bằng chuỗi cần kiểm tra không hoặc ngược lại.
                        if (temp.StartsWith(input) || input.StartsWith(temp))
                        {
                            /// - Bước 4: Nếu thỏa thêm vào danh sách trả về.
                            result.Add(Wards[i].WardName);
                        }

                        if (result.Count >= AutoCompleteHelper.MAXSUGGEST)
                        {
                            break;
                        }
                    }

                    break;
                case DISTRICT:

                    /// - Bước 2: Lấy DS các DTO
                    /// \see DistrictDAO.GetAllDTO();
                    for (int i = 0; i < Districts.Count; i++)
                    {
                        string temp = TranslateHelper.FormatInputString(Districts[i].DistrictName);

                        /// - Bước 3: Kiểm tra Service đó có bắt đầu bằng chuỗi cần kiểm tra không hoặc ngược lại.
                        if (temp.StartsWith(input) || input.StartsWith(temp))
                        {
                            /// - Bước 4: Nếu thỏa thêm vào danh sách trả về.
                            result.Add(Districts[i].DistrictName);
                        }

                        if (result.Count >= AutoCompleteHelper.MAXSUGGEST)
                        {
                            break;
                        }
                    }

                    break;
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Lấy Menu tương ứng.
        /// \param[in] int maDuLieu.
        /// \returns List<ServiceDetailDTO> .
        /// \details <h3>Lấy ra bảng Menu tương ứng với Dịch vụ cần tra cứu</h3>
        /////////////////////////////////////////////////
        public static List<ServiceDetailDTO> GetMenu(int maDuLieu)
        {
            
            List<ServiceDetailDTO> menuOfService = SearchHelper.ConvertServiceDetailDTO(ServiceDetailDAO.getMenuInfo(maDuLieu));
            return menuOfService;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<DistrictDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang DistrictDTO.</h3>
        /////////////////////////////////////////////////
        public static List<DistrictDTO> ConvertDistrictDTO(List<ObjectDTO> objects)
        {
            List<DistrictDTO> result = new List<DistrictDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                DistrictDTO temp = (DistrictDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<WardDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang WardDTO.</h3>
        /////////////////////////////////////////////////
        public static List<WardDTO> ConvertWardDTO(List<ObjectDTO> objects)
        {
            List<WardDTO> result = new List<WardDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                WardDTO temp = (WardDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }        

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<StreetDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang StreetDTO.</h3>
        /////////////////////////////////////////////////
        public static List<StreetDTO> ConvertStreetDTO(List<ObjectDTO> objects)
        {
            List<StreetDTO> result = new List<StreetDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                StreetDTO temp = (StreetDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<LocationDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang LocationDTO.</h3>
        /////////////////////////////////////////////////
        public static List<LocationDTO> ConvertLocationDTO(List<ObjectDTO> objects)
        {
            List<LocationDTO> result = new List<LocationDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                LocationDTO temp = (LocationDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<CityDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang CityDTO.</h3>
        /////////////////////////////////////////////////
        public static List<CityDTO> ConvertCityDTO(List<ObjectDTO> objects)
        {
            List<CityDTO> result = new List<CityDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                CityDTO temp = (CityDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<ServiceDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang ServiceDTO.</h3>
        /////////////////////////////////////////////////
        public static List<ServiceDTO> ConvertServiceDTO(List<ObjectDTO> objects)
        {
            List<ServiceDTO> result = new List<ServiceDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                ServiceDTO temp = (ServiceDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<ServiceDetailDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang ServiceDetailDTO.</h3>
        /////////////////////////////////////////////////
        public static List<ServiceDetailDTO> ConvertServiceDetailDTO(List<ObjectDTO> objects)
        {
            List<ServiceDetailDTO> result = new List<ServiceDetailDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                ServiceDetailDTO temp = (ServiceDetailDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm chuyển đổi 
        /// \param[in] List<ObjectDTO> objects.
        /// \returns  List<DetailDataDTO>.
        /// \details <h3>Giúp chuyển đổi ObjectDTO sang DetailDataDTO.</h3>
        /////////////////////////////////////////////////
        public static List<DetailDataDTO> ConvertDetailDataDTO(List<ObjectDTO> objects)
        {
            List<DetailDataDTO> result = new List<DetailDataDTO>();
            for (int i = 0; i < objects.Count; i++)
            {
                DetailDataDTO temp = (DetailDataDTO)objects[i];
                result.Add(temp);
            }

            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<LocationKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa địa điểm theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<LocationKeyDTO> SearchLocation(string input)
        {
            List<LocationKeyDTO> listLocationKey = new List<LocationKeyDTO>();
            for (int i = 0; i < LocationKeys.Count; i++)
            {
                if (string.Empty != LocationKeys[i].LocationKeyWord && input.IndexOf(LocationKeys[i].LocationKeyWord) != -1)
                {
                    listLocationKey.Add(LocationKeys[i]);
                }
            }

            return listLocationKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<StreetKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa Đường theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<StreetKeyDTO> SearchStreet(string input)
        {
            List<StreetKeyDTO> listStreetKey = new List<StreetKeyDTO>();
            for (int i = 0; i < StreetKeys.Count; i++)
            {
                if (null != StreetKeys[i].StreetKeyWord && input.IndexOf(StreetKeys[i].StreetKeyWord) != -1)
                {
                    listStreetKey.Add(StreetKeys[i]);
                }
            }

            return listStreetKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<WardKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa phường theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<WardKeyDTO> SearchWard(string input)
        {
            List<WardKeyDTO> listWardKey = new List<WardKeyDTO>();
            for (int i = 0; i < WardKeys.Count; i++)
            {
                if (null != WardKeys[i].WardKeyWord && input.IndexOf(WardKeys[i].WardKeyWord) != -1)
                {
                    listWardKey.Add(WardKeys[i]);
                }
            }

            return listWardKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<DistrictKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa Quận/Huyện theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<DistrictKeyDTO> SearchDistrict(string input)
        {
            List<DistrictKeyDTO> listDistrictKey = new List<DistrictKeyDTO>();
            for (int i = 0; i < DistrictKeys.Count; i++)
            {
                if (null != DistrictKeys[i].DistrictKeyWord && input.IndexOf(DistrictKeys[i].DistrictKeyWord) != -1)
                {
                    listDistrictKey.Add(DistrictKeys[i]);
                }
            }

            return listDistrictKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<CityKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa Thành phố theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<CityKeyDTO> SearchCity(string input)
        {
            List<CityKeyDTO> listCityKey = new List<CityKeyDTO>();
            for (int i = 0; i < CityKeys.Count; i++)
            {
                if (null != CityKeys[i].CityKeyWord && input.IndexOf(CityKeys[i].CityKeyWord) != -1)
                {
                    listCityKey.Add(CityKeys[i]);
                }
            }

            return listCityKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm tìm kiếm
        /// \param[in] string input.
        /// \returns List<ServiceKeyDTO> .
        /// \details <h3>Tìm kiếm các từ khóa dịch vụ theo chuỗi.</h3>
        /////////////////////////////////////////////////
        public static List<ServiceKeyDTO> SearchService(string input)
        {
            /// \see ServiceKeyWordDAO.Search(string);
            List<ServiceKeyDTO> listServiceKey = new List<ServiceKeyDTO>();
            for (int i = 0; i < ServiceKeys.Count; i++)
            {
                if (null != ServiceKeys[i].ServiceKeyWord && input.IndexOf(ServiceKeys[i].ServiceKeyWord) != -1)
                {
                    listServiceKey.Add(ServiceKeys[i]);
                }
            }

            /// \see ConvertServiceKey(List<KeyWordDTO>);           
            return listServiceKey;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm kiểm tra chuỗi có chưa số không
        /// \param[in] string strInput.
        /// \returns bool .
        /// \details <h3>Nếu chuổi cần kiểm tra có chứa số thì trả về true, ngược lại false.</h3>
        /////////////////////////////////////////////////
        public static bool CheckExistNumber(string strInput)
        {
            for (int i = 0; i < strInput.Length; i++)
            {
                int a = strInput[i];
                if (a >= '0' && a <= '9')
                {
                    return true;
                }
            }
            return false;
        }

        /////////////////////////////////////////////////
        /// \brief Hàm kiểm kiếm DS đối tượng DataDTO
        /// \param[in] string input.
        /// \returns List<DataDTO> .
        /// \details <h3>Tìm kiếm Danh sách các DataDTO có địa chỉ chứa chuỗi input.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> SearchWithAdress(string input)
        {
            List<DataDTO> result = new List<DataDTO>();

            /// \see DataDAO.SearchWithSoNha(string);
            result = DataDAO.SearchWithSoNha(input);
            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Tìm kiếm Dữ liệu tương ứng
        /// \param[in] SearchResultObject objectCandidate.
        /// \returns List<DataDTO> .
        /// \details <h3>Tìm kiếm danh sách các DataDTO theo các thuộc tính trong đối tượng objectCandidate.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> SearchData(SearchResultObject objectCandidate)
        {
            /// \see DataDAO.Search((string ,int, int,int ,int ,int ,int);
            List<DataDTO> result = DataDAO.Search(objectCandidate);
            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Tìm kiếm Dữ liệu Gốc tương ứng
        /// \param[in] DataDTO data.
        /// \returns ContentDataDTO .
        /// \details <h3>Dựa vào các mã trong đối tượng data tìm ra dữ liệu tương ứng</h3>
        /////////////////////////////////////////////////
        public static ContentDataDTO SearchDataByID(DataDTO data, int index)
        {
            string serviceName = String.Empty;
            string locationName = String.Empty;
            string addressName = String.Empty;
            string streetName = String.Empty;
            string wardName = String.Empty;
            string districtName = String.Empty;
            string cityName = String.Empty;
            string chuthich = String.Empty;
            double kinhdo;
            double vido;
            /// - Bước 1: Tìm đối tượng ServiceDTO có mã dịch vụ tương ứng
            if (data.MaDichVu != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Services.Count; i++)
                {
                    if (SearchHelper.Services[i].ServiceID == data.MaDichVu)
                    {
                        serviceName = SearchHelper.Services[i].ServiceName;
                        break;
                    }
                }
            }

            /// - Bước 2: Tìm đối tượng LocationDTO có mã địa điểm tương ứng
            if (data.MaTenDiaDiem != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Locations.Count; i++)
                {
                    if (SearchHelper.Locations[i].LocationID == data.MaTenDiaDiem)
                    {
                        locationName = SearchHelper.Locations[i].LocationName;
                        break;
                    }
                }
            }

            /// - Bước 3: Tìm đối tượng StreetDTO có mã đường tương ứng
            if (data.MaDuong != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Streets.Count; i++)
                {
                    if (SearchHelper.Streets[i].StreetID == data.MaDuong)
                    {
                        streetName = SearchHelper.Streets[i].StreetName;
                        break;
                    }
                }
            }

            /// - Bước 4: Tìm đối tượng WardDTO có mã phường tương ứng
            if (data.MaPhuong != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Wards.Count; i++)
                {
                    if (SearchHelper.Wards[i].WardID == data.MaPhuong)
                    {
                        wardName = SearchHelper.Wards[i].WardName;
                        break;
                    }
                }
            }

            /// - Bước 5: Tìm đối tượng DistrictDTO có mã Quận/Huyện tương ứng
            if (data.MaQuanHuyen != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Districts.Count; i++)
                {
                    if (SearchHelper.Districts[i].DistrictID == data.MaQuanHuyen)
                    {
                        districtName = SearchHelper.Districts[i].DistrictName;
                        break;
                    }
                }
            }

            /// - Bước 6: Tìm đối tượng CityDTO có mã Tỉnh Thành tương ứng
            if (data.MaTinhThanh != DataConnectionHelper._defaultNumber)
            {
                for (int i = 0; i < SearchHelper.Citys.Count; i++)
                {
                    if (SearchHelper.Citys[i].CityID == data.MaTinhThanh)
                    {
                        cityName = SearchHelper.Citys[i].CityName;
                        break;
                    }
                }
            }

            /// - Bước 7: Gán các giá trị không cần phải tìm kiếm vào kết quả
            addressName = data.SoNha;
            kinhdo = data.KinhDo;
            vido = data.ViDo;
            chuthich = data.ChuThich;
            ContentDataDTO result = new ContentDataDTO(index,data.MaDuLieu, serviceName, locationName, addressName, streetName, wardName, districtName, cityName, kinhdo, vido, chuthich);
            return result;
        }

        /////////////////////////////////////////////////
        /// \brief Xóa những đối tượng trùng
        /// \param[in] List<DataDTO> listData.
        /// \returns List<DataDTO> .
        /// \details <h3>Loại bỏ các đối tượng trùng số nhà.</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> RemoveDuplicate(List<DataDTO> listData)
        {
            List<DataDTO> lstFinal = new List<DataDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string soNha = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (DataDTO dataDTO in listData)
                {
                    soNha = dataDTO.SoNha;
                    if (!uniqueStore.ContainsKey(soNha))
                    {
                        uniqueStore.Add(soNha, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<DataDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<LocationKeyDTO> listData.
        /// \returns List<LocationKeyDTO> .
        /// \details <h3>Loại bỏ các LocationKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<LocationKeyDTO> RemoveDuplicateLocationKey(List<LocationKeyDTO> listData)
        {
            List<LocationKeyDTO> lstFinal = new List<LocationKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (LocationKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.LocationKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<LocationKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<CityKeyDTO> listData.
        /// \returns List<CityKeyDTO> .
        /// \details <h3>Loại bỏ các CityKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<CityKeyDTO> RemoveDuplicateCityKey(List<CityKeyDTO> listData)
        {
            List<CityKeyDTO> lstFinal = new List<CityKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (CityKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.CityKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<CityKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<DistrictKeyDTO> listData.
        /// \returns List<DistrictKeyDTO> .
        /// \details <h3>Loại bỏ các DistrictKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<DistrictKeyDTO> RemoveDuplicateDistrictKey(List<DistrictKeyDTO> listData)
        {
            List<DistrictKeyDTO> lstFinal = new List<DistrictKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (DistrictKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.DistrictKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<DistrictKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<WardKeyDTO> listData.
        /// \returns List<WardKeyDTO> .
        /// \details <h3>Loại bỏ các WardKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<WardKeyDTO> RemoveDuplicateWardKey(List<WardKeyDTO> listData)
        {
            List<WardKeyDTO> lstFinal = new List<WardKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (WardKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.WardKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<WardKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<ServiceKeyDTO> listData.
        /// \returns List<ServiceKeyDTO> .
        /// \details <h3>Loại bỏ các ServiceKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<ServiceKeyDTO> RemoveDuplicateServiceKey(List<ServiceKeyDTO> listData)
        {
            List<ServiceKeyDTO> lstFinal = new List<ServiceKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (ServiceKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.ServiceKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<ServiceKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Key trùng
        /// \param[in] List<StreetKeyDTO> listData.
        /// \returns List<StreetKeyDTO> .
        /// \details <h3>Loại bỏ các StreetKeyDTO có từ khóa giống nhau</h3>
        /////////////////////////////////////////////////
        public static List<StreetKeyDTO> RemoveDuplicateStreetKey(List<StreetKeyDTO> listData)
        {
            List<StreetKeyDTO> lstFinal = new List<StreetKeyDTO>();

            try
            {
                /// - Bước 1: Khai báo một danh sách các chuỗi chưa trùng
                Dictionary<string, int> uniqueStore = new Dictionary<string, int>();

                string keyLocation = string.Empty;

                /// - Bước 2: Duyệt tất cả các DataDTO và kiểm tra xem Số Nhà đã tồn tại chưa. Nếu chưa thì thêm vào.
                foreach (StreetKeyDTO dataDTO in listData)
                {
                    keyLocation = TranslateHelper.FormatInputString(dataDTO.StreetKeyWord);
                    if (!uniqueStore.ContainsKey(keyLocation))
                    {
                        uniqueStore.Add(keyLocation, 0);
                        lstFinal.Add(dataDTO);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                lstFinal = new List<StreetKeyDTO>();
            }

            return lstFinal;
        }

        /////////////////////////////////////////////////
        /// \brief Loại bỏ các Kết Quả trùng
        /// \param[in] List<DataDTO> listData.
        /// \returns List<DataDTO> .
        /// \details <h3>Loại bỏ các DataDTO có mã dữ liệu trùng nhau</h3>
        /////////////////////////////////////////////////
        public static List<DataDTO> RemoveDuplicateResult(List<DataDTO> listData)
        {
            List<DataDTO> lstFinal = new List<DataDTO>();
            lstFinal = (from data in listData select data).Distinct(new MethodExtention()).ToList();
            return lstFinal;
        }

    }
}
